from forest.resource import Resources, Resource, ValidationError

from string import Template

class Repository(Resource):
    ''' Registers a repository to download packages from.

        Example::

            resources:
              - $: repository
                name: Fedorareleasever-basearch
                url: "https://mirrors.fedoraproject.org/metalink?repo=fedora-$release&arch=$architecture"
                type: metalink

              - $: repository
                name: Fedorareleasever-basearch-Updates
                url: "https://mirrors.fedoraproject.org/metalink?repo=updates-released-f$release&arch=$architecture"
                type: metalink

        .. describe:: name

            Required. The name of the repository.

        .. describe:: url

            Required. The url to the repository. Must be prefixed with a file:// or http://

        .. describe:: type

            Optional. Defaults to "url". If the url is a metalink, specify "metalink". If the url is a mirror list specify "mirrorlist".

        .. describe:: embed

            Optional. Defaults to True. create the repository file with specified values in /etc/yum.repos.d/

    '''
    __register__ = "repository"

    def __init__(self, config, resources):
        super(Repository, self).__init__(config, resources)
        self.url_subs = None
        self.name_subs = None
        self.set_subs()

    def set_subs(self):
        if self.url_subs is not None and self.name_subs is not None:
            return True

        try:
            architecture = self.config.get('yum.architecture')
            release = self.config.get('yum.release')

            raw_name = self.get_name()
            raw_name = raw_name.replace(' ', '_')
            template_name =Template(raw_name)
            self.name_subs = template_name.safe_substitute(architecture = architecture, release = release)

            template_url=Template(self.get_url())
            self.url_subs = template_url.safe_substitute(architecture = architecture, release = release)
            return True
        except Exception:
            return False


    def get_id(self):
        return 'repository:' + self.get_name()

    def get_name(self):
        return self.value.get('name')#.replace(' ', '_')

    def get_name_subs(self):
        if self.name_subs is None and not self.set_subs():
            return self.get_name()
        return self.name_subs


    def get_url_subs(self):
        if self.url_subs is None and not self.set_subs():
            return self.get_url()
        return self.url_subs

    def get_url(self):
        return self.value.get('url')

    def get_embed(self):
        return self.value.get('embed', True)

    def get_type(self):
        return self.value.get('type', 'url')

    def get_gpgcheck(self):
        return self.value.get('gpgcheck', 0)

    def get_gpgkey(self):
        return self.value.get('gpgkey', None)

    def validate(self):

        valid_keys = ['type', 'name', 'url', 'gpgcheck', 'gpgkey', 'embed']

        for k in self.value.iterkeys():
            if k in valid_keys:
                continue
            raise ValidationError("Undefined repository option {}".format(k))

        necessary_keys = ['name', 'url']

        for necessary in necessary_keys:
            if necessary in self.value:
                continue
            print self.value
            raise ValidationError("Missing repository option {}. Please specify it.".format(necessary))

        #if self.get_name().find(' ') != -1:
        #    raise ValidationError("Repository name musn't contain spaces!")

    def serialize(self):

        str_l = []

        #basearch = self.config.get('yum.architecture')
        #release = self.config.get('yum.release')

        #template_name =Template(self.get_name())
        #name = template_name.safe_substitute(basearch = basearch, release = release)
        self.set_subs()
        #header
        str_l.append('[{}]'.format(self.get_name_subs()))

        #adding them line by line
        str_l.append('='.join(['name',self.get_name_subs()]))

        # default for type is 'url', so set it to 'baseurl' if None
        repo_type = self.get_type()
        if repo_type is None or repo_type == 'url':
            repo_type = 'baseurl'

        #template_url=Template(self.get_url())
        #url = template_url.safe_substitute(basearch = basearch, release = release)

        str_l.append('='.join([repo_type, self.get_url_subs()]))
        str_l.append('='.join(['gpgcheck', str(self.get_gpgcheck())]))
        gpg_key = self.get_gpgkey()
        if gpg_key is not None:
            str_l.append('='.join(['gpgkey', gpg_key]))

        return '\n'.join(str_l)
